<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>装饰器模式</title>
</head>
<body>

</body>
</html>

<script>
  // 模拟传统面向对象语言的装饰者模式
  var Plane = function () {
  };

  Plane.prototype.fire = function () {
    console.log('发射普通子弹');
  };


  // 装饰类
  var MissileDecorator = function (plane) {
    this.plane = plane;
  }

  MissileDecorator.prototype.fire = function () {
    this.plane.fire();
    console.log('发射导弹!');
  };

  var plane = new Plane();
  plane = new MissileDecorator(plane);
  plane.fire();

  // JavaScript中的装饰器模式
  var Plane = {
    fire: function () {
      console.log('发射普通的子弹');
    }
  };
  var missileDecorator= function () {
    console.log('发射导弹!');
  };

  var fire = Plane.fire;

  Plane.fire=function () {
    fire();
    missileDecorator();
  };

  Plane.fire();

  // 对 window.onload 进行装饰例子
  window.onload=function () {
    console.log('onload');
  };

  var  _onload= window.onload || function () {};

  window.onload=function () {
    _onload();
    console.log('自己的处理函数');
  };

  // 表单验证
  Function.prototype.before=function (beforefn) {
    var _this= this;                               //保存旧函数的引用
    return function () {                           //返回包含旧函数和新函数的“代理”函数
      beforefn.apply(this,arguments);            //执行新函数,且保证this不被劫持,新函数接受的参数
      // 也会被原封不动的传入旧函数,新函数在旧函数之前执行
      return _this.apply(this,arguments);
    };
  };

  var validata=function () {
    if(username.value===''){
      alert('用户名不能为空!')
      return false;
    }
    if(password.value===''){
      alert('密码不能为空!')
      return false;
    }
  }

  var formSubmit=function () {
    var param={
      username: username.value,
      password: password.value
    }

    ajax('post','http://www.xxx.com',param);
  }

  formSubmit= formSubmit.before(validata);


  submitBtn.onclick=function () {
    formSubmit();
  }
</script>
